#ifndef _CONSOLE_PROGRESS_REPORTER_H_
#define _CONSOLE_PROGRESS_REPORTER_H_

#include <string>
#include "scoped_callback.h"

class ConsoleProgressReporter{
	std::vector<std::pair<std::string,std::string>> formated_progress_info_;
public:
	template<typename T>	
	void AddProgressInfo(T progress_info)
	{
		ScopedCallback scoped_callback([&](){this->OutputProgress();});
		for(auto i = formated_progress_info_.begin();i != formated_progress_info_.end();++i)
		{
			if(i->first == progress_info.GetProgressName())
			{
				i->second = progress_info.FormatInfoString();
				return;
			}
		}
		formated_progress_info_ .push_back(
			std::make_pair(progress_info.GetProgressName(),progress_info.FormatInfoString()) );
	}

	void ClearProgress()
	{
		formated_progress_info_.clear();
	}
	void OutputProgress()
	{
		std::string s;
		for(auto it = formated_progress_info_.begin(); it != formated_progress_info_.end(); ++it)
		{
			s+=it->second;
		}
		printf("\r %s", s.c_str());
	}
};

#include <sstream>
struct photon_tracing_progress_reporter{
	const int traced_caustic_photons_, traced_indirect_photons_,traced_direct_photons_;
	photon_tracing_progress_reporter(int caustic, int indirect,int direct):
	traced_caustic_photons_(caustic),traced_indirect_photons_(indirect),traced_direct_photons_(direct){}
	std::string FormatInfoString()const
	{
		std::stringstream ss;		
		ss<<"traced caustic photons:" << traced_caustic_photons_ <<",";
		ss<<"traced indirect photons:" <<traced_indirect_photons_<<",";
		ss<<"traced direct photons:" <<traced_direct_photons_<<" ";
		return ss.str();
	}
	std::string GetProgressName()const
	{
		return "photon_tracing_progress_reporter";
	}
};
struct ray_tracing_progress_reporter{
	const int traced_rays_, total_ray_count_;
	ray_tracing_progress_reporter(int traced_ray, int total_ray):
	traced_rays_(traced_ray),total_ray_count_(total_ray){}
	std::string FormatInfoString()const
	{
		std::stringstream ss;		
		ss<<"traced rays:" << traced_rays_ <<"/"<<total_ray_count_ << " ";
		return ss.str();
	}
	std::string GetProgressName()const
	{
		return "ray_tracing_progress_reporter";
	}
};
#endif